[commit: ghc] master: Reject top-level typed TH splices. Fixes #10945 (1750ebc)

git at git.haskell.org git at git.haskell.org
Tue Oct 20 18:26:41 UTC 2015


Repository : ssh://git@git.haskell.org/ghc

On branch  : master
Link       : http://ghc.haskell.org/trac/ghc/changeset/1750ebc2e40bab85246717326d3d5c60f132e652/ghc

>---------------------------------------------------------------

commit 1750ebc2e40bab85246717326d3d5c60f132e652
Author: Jan Stolarek <jan.stolarek at p.lodz.pl>
Date:   Tue Oct 20 14:09:13 2015 +0200

    Reject top-level typed TH splices. Fixes #10945
    
    When TemplateHaskell language extension is enabled it is valid to have
    top-level expressions.  Each such expression is treated as a contents
    of a splice.  The problem arises with typed splices.  They are not valid
    at the top level and therefore we should interpret them not as a splice
    but as a top-level expression (aka. implicit splice).  So saying:
    
    $$foo
    
    is equivalent of:
    
    $( $$foo )
    
    This patch makes sure that this is indeed the case.  Until now we
    incorrectly treated typed splices as explicit splices.


>---------------------------------------------------------------

1750ebc2e40bab85246717326d3d5c60f132e652
 compiler/parser/RdrHsSyn.hs      | 15 +++++++++++----
 testsuite/tests/th/T10945.stderr | 29 +++++++++++++++++++++++++++++
 testsuite/tests/th/all.T         |  2 +-
 3 files changed, 41 insertions(+), 5 deletions(-)

diff --git a/compiler/parser/RdrHsSyn.hs b/compiler/parser/RdrHsSyn.hs
index 8bc4f6c..e64a575 100644
--- a/compiler/parser/RdrHsSyn.hs
+++ b/compiler/parser/RdrHsSyn.hs
@@ -263,11 +263,18 @@ mkSpliceDecl :: LHsExpr RdrName -> HsDecl RdrName
 -- but if she wrote, say,
 --      f x            then behave as if she'd written $(f x)
 --                     ie a SpliceD
+--
+-- Typed splices are not allowed at the top level, thus we do not represent them
+-- as spliced declaration.  See #10945
 mkSpliceDecl lexpr@(L loc expr)
-  | HsSpliceE splice <- expr = SpliceD (SpliceDecl (L loc splice) ExplicitSplice)
-  | otherwise                = SpliceD (SpliceDecl (L loc splice) ImplicitSplice)
-  where
-    splice = mkUntypedSplice lexpr
+  | HsSpliceE splice@(HsUntypedSplice {}) <- expr
+  = SpliceD (SpliceDecl (L loc splice) ExplicitSplice)
+
+  | HsSpliceE splice@(HsQuasiQuote {}) <- expr
+  = SpliceD (SpliceDecl (L loc splice) ExplicitSplice)
+
+  | otherwise
+  = SpliceD (SpliceDecl (L loc (mkUntypedSplice lexpr)) ImplicitSplice)
 
 mkRoleAnnotDecl :: SrcSpan
                 -> Located RdrName                   -- type being annotated
diff --git a/testsuite/tests/th/T10945.stderr b/testsuite/tests/th/T10945.stderr
new file mode 100644
index 0000000..0c1d949
--- /dev/null
+++ b/testsuite/tests/th/T10945.stderr
@@ -0,0 +1,29 @@
+
+T10945.hs:7:11:
+    Couldn't match expected type ‘TExp DecsQ’ with actual type ‘[Dec]’
+    In the first argument of ‘return’, namely
+      ‘[SigD
+          (mkName "m")
+          (ForallT
+             [PlainTV (mkName "a")]
+             []
+             (AppT (AppT ArrowT (VarT (mkName "a"))) (VarT (mkName "a")))),
+        FunD (mkName "m") [Clause [...] (NormalB (VarE (mkName "x"))) []]]’
+    In the expression:
+      return
+        [SigD
+           (mkName "m")
+           (ForallT
+              [PlainTV (mkName "a")]
+              []
+              (AppT (AppT ArrowT (VarT (mkName "a"))) (VarT (mkName "a")))),
+         FunD (mkName "m") [Clause [...] (NormalB (VarE (mkName "x"))) []]]
+    In the Template Haskell splice
+      $$(return
+           [SigD
+              (mkName "m")
+              (ForallT
+                 [PlainTV (mkName "a")]
+                 []
+                 (AppT (AppT ArrowT (VarT (mkName "a"))) (VarT (mkName "a")))),
+            FunD (mkName "m") [Clause [...] (NormalB (VarE (mkName "x"))) []]])
diff --git a/testsuite/tests/th/all.T b/testsuite/tests/th/all.T
index 1e05d72..3d08f36 100644
--- a/testsuite/tests/th/all.T
+++ b/testsuite/tests/th/all.T
@@ -366,5 +366,5 @@ test('T10796b', normal, compile_fail, ['-v0'])
 test('T10811', normal, compile, ['-v0'])
 test('T10810', normal, compile, ['-v0'])
 test('T10891', normal, compile, ['-v0'])
-test('T10945', expect_broken(10945), compile, ['-v0'])
+test('T10945', normal, compile_fail, ['-v0'])
 test('T10946', expect_broken(10946), compile, ['-v0'])



More information about the ghc-commits mailing list