diff options
author | nineonine <mail4chemik@gmail.com> | 2019-10-07 13:45:29 -0500 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2019-10-13 06:31:40 -0400 |
commit | 5ab1a28d91e2e5331bf20b1e3dc0dff793ebca8b (patch) | |
tree | b3895afbc4efd028c0bc0a0f224461d2e9c4a3a4 | |
parent | 226d86d29842f894869e23ddb1197d04dacae7f7 (diff) | |
download | haskell-5ab1a28d91e2e5331bf20b1e3dc0dff793ebca8b.tar.gz |
Template Haskell: make unary tuples legal (#16881)
-rw-r--r-- | compiler/GHC/ThToHs.hs | 9 | ||||
-rw-r--r-- | docs/users_guide/8.10.1-notes.rst | 4 | ||||
-rw-r--r-- | libraries/template-haskell/Language/Haskell/TH/Syntax.hs | 31 | ||||
-rw-r--r-- | testsuite/tests/th/TH_1tuple.stderr | 10 | ||||
-rw-r--r-- | testsuite/tests/th/TH_Promoted1Tuple.stderr | 5 | ||||
-rw-r--r-- | testsuite/tests/th/TH_tuple1.hs | 18 | ||||
-rw-r--r-- | testsuite/tests/th/TH_tuple1.stdout | 10 | ||||
-rw-r--r-- | testsuite/tests/th/TH_tuple1a.hs | 29 | ||||
-rw-r--r-- | testsuite/tests/th/all.T | 3 |
9 files changed, 71 insertions, 48 deletions
diff --git a/compiler/GHC/ThToHs.hs b/compiler/GHC/ThToHs.hs index f49d6ff0b2..8c3e6a5f1e 100644 --- a/compiler/GHC/ThToHs.hs +++ b/compiler/GHC/ThToHs.hs @@ -1368,12 +1368,7 @@ cvtTypeKind ty_str ty TupleT n | Just normals <- m_normals , normals `lengthIs` n -- Saturated - -> if n==1 then return (head normals) -- Singleton tuples treated - -- like nothing (ie just parens) - else returnL (HsTupleTy noExtField - HsBoxedOrConstraintTuple normals) - | n == 1 - -> failWith (ptext (sLit ("Illegal 1-tuple " ++ ty_str ++ " constructor"))) + -> returnL (HsTupleTy noExtField HsBoxedOrConstraintTuple normals) | otherwise -> mk_apps (HsTyVar noExtField NotPromoted (noLoc (getRdrName (tupleTyCon Boxed n)))) @@ -1491,8 +1486,6 @@ cvtTypeKind ty_str ty -- Promoted data constructor; hence cName PromotedTupleT n - | n == 1 - -> failWith (ptext (sLit ("Illegal promoted 1-tuple " ++ ty_str))) | Just normals <- m_normals , normals `lengthIs` n -- Saturated -> returnL (HsExplicitTupleTy noExtField normals) diff --git a/docs/users_guide/8.10.1-notes.rst b/docs/users_guide/8.10.1-notes.rst index 77c1469639..3251b326d5 100644 --- a/docs/users_guide/8.10.1-notes.rst +++ b/docs/users_guide/8.10.1-notes.rst @@ -171,6 +171,10 @@ Template Haskell :extension:`DeriveLift` has been simplified to take advantage of expression quotations. +- Explicit boxed 1-tuples from `HsSyn` are now treated as actual 1-tuples, + without flattening. In most of the cases these will be obtained using + Template Haskell since it is uncommon to deal with 1-tuples in the source. + ``ghc-prim`` library ~~~~~~~~~~~~~~~~~~~~ diff --git a/libraries/template-haskell/Language/Haskell/TH/Syntax.hs b/libraries/template-haskell/Language/Haskell/TH/Syntax.hs index 59cc5dceef..81cd588ec8 100644 --- a/libraries/template-haskell/Language/Haskell/TH/Syntax.hs +++ b/libraries/template-haskell/Language/Haskell/TH/Syntax.hs @@ -1534,20 +1534,8 @@ tupleDataName :: Int -> Name -- | Tuple type constructor tupleTypeName :: Int -> Name -tupleDataName 0 = mk_tup_name 0 DataName -tupleDataName 1 = error "tupleDataName 1" -tupleDataName n = mk_tup_name (n-1) DataName - -tupleTypeName 0 = mk_tup_name 0 TcClsName -tupleTypeName 1 = error "tupleTypeName 1" -tupleTypeName n = mk_tup_name (n-1) TcClsName - -mk_tup_name :: Int -> NameSpace -> Name -mk_tup_name n_commas space - = Name occ (NameG space (mkPkgName "ghc-prim") tup_mod) - where - occ = mkOccName ('(' : replicate n_commas ',' ++ ")") - tup_mod = mkModName "GHC.Tuple" +tupleDataName n = mk_tup_name n DataName True +tupleTypeName n = mk_tup_name n TcClsName True -- Unboxed tuple data and type constructors -- | Unboxed tuple data constructor @@ -1555,15 +1543,18 @@ unboxedTupleDataName :: Int -> Name -- | Unboxed tuple type constructor unboxedTupleTypeName :: Int -> Name -unboxedTupleDataName n = mk_unboxed_tup_name n DataName -unboxedTupleTypeName n = mk_unboxed_tup_name n TcClsName +unboxedTupleDataName n = mk_tup_name n DataName False +unboxedTupleTypeName n = mk_tup_name n TcClsName False -mk_unboxed_tup_name :: Int -> NameSpace -> Name -mk_unboxed_tup_name n space +mk_tup_name :: Int -> NameSpace -> Bool -> Name +mk_tup_name n space boxed = Name (mkOccName tup_occ) (NameG space (mkPkgName "ghc-prim") tup_mod) where - tup_occ | n == 1 = "Unit#" -- See Note [One-tuples] in TysWiredIn - | otherwise = "(#" ++ replicate n_commas ',' ++ "#)" + withParens thing + | boxed = "(" ++ thing ++ ")" + | otherwise = "(#" ++ thing ++ "#)" + tup_occ | n == 1 = if boxed then "Unit" else "Unit#" + | otherwise = withParens (replicate n_commas ',') n_commas = n - 1 tup_mod = mkModName "GHC.Tuple" diff --git a/testsuite/tests/th/TH_1tuple.stderr b/testsuite/tests/th/TH_1tuple.stderr index 5e9d6c799d..bc7f25ad81 100644 --- a/testsuite/tests/th/TH_1tuple.stderr +++ b/testsuite/tests/th/TH_1tuple.stderr @@ -1,5 +1,7 @@ -TH_1tuple.hs:11:7: - Illegal 1-tuple type constructor - When splicing a TH expression: 1 :: () - In the untyped splice: $(sigE [| 1 |] (tupleT 1)) +TH_1tuple.hs:11:7: error: + • Expecting one more argument to ‘Unit’ + Expected a type, but ‘Unit’ has kind ‘* -> *’ + • In an expression type signature: Unit + In the expression: (1 :: Unit) + In an equation for ‘y’: y = (1 :: Unit) diff --git a/testsuite/tests/th/TH_Promoted1Tuple.stderr b/testsuite/tests/th/TH_Promoted1Tuple.stderr index bcda8189e0..a996623c30 100644 --- a/testsuite/tests/th/TH_Promoted1Tuple.stderr +++ b/testsuite/tests/th/TH_Promoted1Tuple.stderr @@ -1,4 +1,3 @@ -TH_Promoted1Tuple.hs:7:3: - Illegal promoted 1-tuple type - When splicing a TH declaration: type F = '(GHC.Types.Int) +TH_Promoted1Tuple.hs:7:3: error: + Illegal type: ‘'(Int)’ Perhaps you intended to use DataKinds diff --git a/testsuite/tests/th/TH_tuple1.hs b/testsuite/tests/th/TH_tuple1.hs index 3e9b330fb0..f2d1baf3a4 100644 --- a/testsuite/tests/th/TH_tuple1.hs +++ b/testsuite/tests/th/TH_tuple1.hs @@ -1,15 +1,9 @@ -{-# LANGUAGE TemplateHaskell #-} - --- Test the use of tupleDataName, tupleTypeName - -module ShouldCompile where +module Main where import Language.Haskell.TH +import TH_tuple1a -foo = $( sigE (appsE [conE (tupleDataName 2), - litE (integerL 1), - litE (integerL 2)]) - (appT (appT (conT (tupleTypeName 2)) - (conT ''Integer)) - (conT ''Integer)) - ) +main :: IO () +main = do + let pprQ = \a -> print a >> (putStrLn $ pprint a) + mapM_ (\q -> runQ q >>= pprQ) [tp2, tp1, tp2u, tp1u] diff --git a/testsuite/tests/th/TH_tuple1.stdout b/testsuite/tests/th/TH_tuple1.stdout new file mode 100644 index 0000000000..7e35530f6c --- /dev/null +++ b/testsuite/tests/th/TH_tuple1.stdout @@ -0,0 +1,10 @@ +SigE (AppE (AppE (ConE GHC.Tuple.(,)) (LitE (IntegerL 1))) (LitE (IntegerL 2))) (AppT (AppT (ConT GHC.Tuple.(,)) (ConT GHC.Integer.Type.Integer)) (ConT GHC.Integer.Type.Integer)) +GHC.Tuple.(,) 1 2 :: GHC.Tuple.(,) GHC.Integer.Type.Integer + GHC.Integer.Type.Integer +SigE (AppE (ConE GHC.Tuple.Unit) (LitE (IntegerL 1))) (AppT (ConT GHC.Tuple.Unit) (ConT GHC.Integer.Type.Integer)) +GHC.Tuple.Unit 1 :: GHC.Tuple.Unit GHC.Integer.Type.Integer +SigE (AppE (AppE (ConE GHC.Tuple.(#,#)) (LitE (IntegerL 1))) (LitE (IntegerL 2))) (AppT (AppT (ConT GHC.Tuple.(#,#)) (ConT GHC.Integer.Type.Integer)) (ConT GHC.Integer.Type.Integer)) +GHC.Tuple.(#,#) 1 2 :: GHC.Tuple.(#,#) GHC.Integer.Type.Integer + GHC.Integer.Type.Integer +SigE (AppE (ConE GHC.Tuple.Unit#) (LitE (IntegerL 1))) (AppT (ConT GHC.Tuple.Unit#) (ConT GHC.Integer.Type.Integer)) +GHC.Tuple.Unit# 1 :: GHC.Tuple.Unit# GHC.Integer.Type.Integer diff --git a/testsuite/tests/th/TH_tuple1a.hs b/testsuite/tests/th/TH_tuple1a.hs new file mode 100644 index 0000000000..2b4bb5014b --- /dev/null +++ b/testsuite/tests/th/TH_tuple1a.hs @@ -0,0 +1,29 @@ +{-# LANGUAGE TemplateHaskell #-} +-- Test the use of tupleDataName, tupleTypeName +module TH_tuple1a where + +import Language.Haskell.TH + +tp2 = sigE (appsE [conE (tupleDataName 2), + litE (integerL 1), + litE (integerL 2)]) + (appT (appT (conT (tupleTypeName 2)) + (conT ''Integer)) + (conT ''Integer)) + +tp1 = sigE (appsE [conE (tupleDataName 1), + litE (integerL 1)]) + (appT (conT (tupleTypeName 1)) + (conT ''Integer)) + +tp2u = sigE (appsE [conE (unboxedTupleDataName 2), + litE (integerL 1), + litE (integerL 2)]) + (appT (appT (conT (unboxedTupleTypeName 2)) + (conT ''Integer)) + (conT ''Integer)) + +tp1u = sigE (appsE [conE (unboxedTupleDataName 1), + litE (integerL 1)]) + (appT (conT (unboxedTupleTypeName 1)) + (conT ''Integer)) diff --git a/testsuite/tests/th/all.T b/testsuite/tests/th/all.T index 590b060b0b..cbd40f6edd 100644 --- a/testsuite/tests/th/all.T +++ b/testsuite/tests/th/all.T @@ -102,7 +102,8 @@ test('TH_spliceE3', normal, compile, ['-v0']) test('TH_spliceE4', normal, compile_and_run, ['']) test('TH_class1', normal, compile, ['-v0']) -test('TH_tuple1', normal, compile, ['-v0']) +test('TH_tuple1', [], multimod_compile_and_run, + ['TH_tuple1', '-v0 ' + config.ghc_th_way_flags]) test('TH_genEx', [], multimod_compile, ['TH_genEx', '-v0 ' + config.ghc_th_way_flags]) |