Commit 82023524 authored by Matthew Pickering's avatar Matthew Pickering Committed by Marge Bot

TemplateHaskellQuotes: Allow nested splices

There is no issue with nested splices as they do not require any compile
time code execution. All execution is delayed until the top-level
splice.
parent 58a4ddef
......@@ -270,9 +270,10 @@ rnSpliceGen run_splice pend_splice splice
; writeMutVar ps_var (pending_splice : ps)
; return (result, fvs) }
_ -> do { (splice', fvs1) <- checkNoErrs $
setStage (Splice splice_type) $
rnSplice splice
_ -> do { checkTopSpliceAllowed splice
; (splice', fvs1) <- checkNoErrs $
setStage (Splice splice_type) $
rnSplice splice
-- checkNoErrs: don't attempt to run the splice if
-- renaming it failed; otherwise we get a cascade of
-- errors from e.g. unbound variables
......@@ -284,6 +285,22 @@ rnSpliceGen run_splice pend_splice splice
then Typed
else Untyped
-- Nested splices are fine without TemplateHaskell because they
-- are not executed until the top-level splice is run.
checkTopSpliceAllowed :: HsSplice GhcPs -> RnM ()
checkTopSpliceAllowed splice = do
let (herald, ext) = spliceExtension splice
extEnabled <- xoptM ext
unless extEnabled
(failWith $ text herald <+> text "are not permitted without" <+> ppr ext)
where
spliceExtension :: HsSplice GhcPs -> (String, LangExt.Extension)
spliceExtension (HsQuasiQuote {}) = ("Quasi-quotes", LangExt.QuasiQuotes)
spliceExtension (HsTypedSplice {}) = ("Top-level splices", LangExt.TemplateHaskell)
spliceExtension (HsUntypedSplice {}) = ("Top-level splices", LangExt.TemplateHaskell)
spliceExtension s = pprPanic "spliceExtension" (ppr s)
------------------
-- | Returns the result of running a splice and the modFinalizers collected
......@@ -644,7 +661,8 @@ rnSpliceDecl (XSpliceDecl nec) = noExtCon nec
rnTopSpliceDecls :: HsSplice GhcPs -> RnM ([LHsDecl GhcPs], FreeVars)
-- Declaration splice at the very top level of the module
rnTopSpliceDecls splice
= do { (rn_splice, fvs) <- checkNoErrs $
= do { checkTopSpliceAllowed splice
; (rn_splice, fvs) <- checkNoErrs $
setStage (Splice Untyped) $
rnSplice splice
-- As always, be sure to checkNoErrs above lest we end up with
......
......@@ -1450,9 +1450,9 @@ varsym_prefix :: Action
varsym_prefix = sym $ \exts s ->
if | TypeApplicationsBit `xtest` exts, s == fsLit "@"
-> return ITtypeApp
| ThBit `xtest` exts, s == fsLit "$"
| ThQuotesBit `xtest` exts, s == fsLit "$"
-> return ITdollar
| ThBit `xtest` exts, s == fsLit "$$"
| ThQuotesBit `xtest` exts, s == fsLit "$$"
-> return ITdollardollar
| s == fsLit "!" -> return ITbang
| s == fsLit "~" -> return ITtilde
......@@ -2786,7 +2786,7 @@ srcParseErr options buf len
last100 = decodePrevNChars 100 buf
doInLast100 = "do" `isInfixOf` last100
mdoInLast100 = "mdo" `isInfixOf` last100
th_enabled = ThBit `xtest` pExtsBitmap options
th_enabled = ThQuotesBit `xtest` pExtsBitmap options
ps_enabled = PatternSynonymsBit `xtest` pExtsBitmap options
-- Report a parse failure, giving the span of the previous token as
......
......@@ -46,6 +46,9 @@ Template Haskell
``where`` bindings properly. Previously, such fixity declarations would
be dropped when quoted due to a Template Haskell bug.
- The ``-XTemplateHaskellQuotes`` extension now allows nested splices as nested
splices do not lead directly to compile-time evaluation. (!2288)
``ghc-prim`` library
~~~~~~~~~~~~~~~~~~~~
......
......@@ -48,7 +48,7 @@ Syntax
Template Haskell has the following new syntactic constructions. You need to use
the extension :extension:`TemplateHaskell` to switch these syntactic extensions on.
Alternatively, the :extension:`TemplateHaskellQuotes` extension can be used to
enable the quotation subset of Template Haskell (i.e. without splice syntax).
enable the quotation subset of Template Haskell (i.e. without top-level splices).
The :extension:`TemplateHaskellQuotes` extension is considered safe under
:ref:`safe-haskell` while :extension:`TemplateHaskell` is not.
......
{-# LANGUAGE TemplateHaskellQuotes #-}
module TH_double_splice where
-- Should be a compile time error as TemplateHaskell is not enabled.
foo = [| $($(error "should not happen")) |]
TH_double_splice.hs:6:12: error:
• Top-level splices are not permitted without TemplateHaskell
• In the untyped splice: $(error "should not happen")
In the untyped splice: $($(error "should not happen"))
In the Template Haskell quotation
[| $($(error "should not happen")) |]
{-# LANGUAGE TemplateHaskellQuotes #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
module TH_nested_splice where
a = [| 5 |]
b = [| $(a) |]
c = [|| 5 ||]
d = [|| $$(c) ||]
{-# LANGUAGE TemplateHaskellQuotes #-}
module TH_top_splice where
-- Should be a compile time error as TemplateHaskell is not enabled.
foo = $([| 1 |])
TH_top_splice.hs:6:7: error:
• Top-level splices are not permitted without TemplateHaskell
• In the untyped splice: $([| 1 |])
{-# LANGUAGE TemplateHaskellQuotes #-}
module TTH_top_splice where
-- Should be a compile time error as TemplateHaskell is not enabled.
qux = $$([|| 1 ||])
TTH_top_splice.hs:6:7: error:
• Top-level splices are not permitted without TemplateHaskell
• In the typed splice: $$([|| 1 ||])
......@@ -30,3 +30,7 @@ test('TH_repE3', normal, compile, [''])
test('TH_abstractFamily', normal, compile_fail, [''])
test('TH_localname', normal, compile_fail, [''])
test('TH_typed_csp', normal, compile, [''])
test('TH_nested_splice', normal, compile, [''])
test('TH_top_splice', normal, compile_fail, [''])
test('TTH_top_splice', normal, compile_fail, [''])
test('TH_double_splice', normal, compile_fail, [''])
......@@ -8,6 +8,5 @@ SafeLang12_B.hs:2:14: warning:
[2 of 3] Compiling SafeLang12_B ( SafeLang12_B.hs, SafeLang12_B.o )
[3 of 3] Compiling Main ( SafeLang12.hs, SafeLang12.o )
SafeLang12.hs:8:1: error:
parse error on input ‘$’
Perhaps you intended to use TemplateHaskell
SafeLang12.hs:1:1: error:
Top-level splices are not permitted without TemplateHaskell
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment