Make okConIdOcc recognize unboxed tuples
authorRyan Scott <ryan.gl.scott@gmail.com>
Mon, 18 Jul 2016 17:51:53 +0000 (13:51 -0400)
committerRyan Scott <ryan.gl.scott@gmail.com>
Mon, 18 Jul 2016 17:51:53 +0000 (13:51 -0400)
Summary:
`okConIdOcc`, which validates that a type or constructor name is valid
for splicing using Template Haskell, has a special case for tuples, but
neglects to look for unboxed tuples, causing some sensible Template Haskell
code involving unboxed tuples to be rejected.

Fixes #12407.

Test Plan: make test TEST=T12407

Reviewers: austin, bgamari, hvr, goldfire

Reviewed By: goldfire

Subscribers: thomie

Differential Revision: https://phabricator.haskell.org/D2410

GHC Trac Issues: #12407

compiler/basicTypes/Lexeme.hs
testsuite/tests/th/T12407.hs [new file with mode: 0644]
testsuite/tests/th/all.T

index 22515c1..ef5fa12 100644 (file)
@@ -154,18 +154,23 @@ okVarSymOcc str = all okSymChar str &&
 -- starts with an acceptable letter?
 okConIdOcc :: String -> Bool
 okConIdOcc str = okIdOcc str ||
-                 is_tuple_name1 str
+                 is_tuple_name1 True  str ||
+                   -- Is it a boxed tuple...
+                 is_tuple_name1 False str
+                   -- ...or an unboxed tuple (Trac #12407)?
   where
     -- check for tuple name, starting at the beginning
-    is_tuple_name1 ('(' : rest) = is_tuple_name2 rest
-    is_tuple_name1 _            = False
+    is_tuple_name1 True  ('(' : rest)       = is_tuple_name2 True  rest
+    is_tuple_name1 False ('(' : '#' : rest) = is_tuple_name2 False rest
+    is_tuple_name1 _     _                  = False
 
     -- check for tuple tail
-    is_tuple_name2 ")"          = True
-    is_tuple_name2 (',' : rest) = is_tuple_name2 rest
-    is_tuple_name2 (ws  : rest)
-      | isSpace ws              = is_tuple_name2 rest
-    is_tuple_name2 _            = False
+    is_tuple_name2 True  ")"          = True
+    is_tuple_name2 False "#)"         = True
+    is_tuple_name2 boxed (',' : rest) = is_tuple_name2 boxed rest
+    is_tuple_name2 boxed (ws  : rest)
+      | isSpace ws                    = is_tuple_name2 boxed rest
+    is_tuple_name2 _     _            = False
 
 -- | Is this an acceptable symbolic constructor name, assuming it
 -- starts with an acceptable character?
diff --git a/testsuite/tests/th/T12407.hs b/testsuite/tests/th/T12407.hs
new file mode 100644 (file)
index 0000000..daa3e34
--- /dev/null
@@ -0,0 +1,17 @@
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE UnboxedTuples #-}
+module T12407 where
+
+import Language.Haskell.TH.Lib
+import Language.Haskell.TH.Syntax
+
+$(do let ubxTup = conT (unboxedTupleTypeName 2) `appT` conT ''Int
+                                                `appT` conT ''Int
+     x <- newName "x"
+     y <- newName "y"
+
+     [d| f :: $(ubxTup) -> $(ubxTup)
+         f $(conP (unboxedTupleDataName 2) [varP x, varP y])
+             = $(conE (unboxedTupleDataName 2) `appE` varE x
+                                               `appE` varE y)
+      |])
index 3f448d7..5cece92 100644 (file)
@@ -420,3 +420,4 @@ test('T12130', extra_clean(['T12130a.hi','T12130a.o']),
               multimod_compile, ['T12130', '-v0 ' + config.ghc_th_way_flags])
 test('T12403', omit_ways(['ghci']),
               compile_and_run, ['-v0 -ddump-splices -dsuppress-uniques'])
+test('T12407', omit_ways(['ghci']), compile, ['-v0'])