summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorRyan Scott <ryan.gl.scott@gmail.com>2020-04-27 17:08:19 -0400
committerBen Gamari <ben@smart-cactus.org>2020-05-31 18:03:38 -0400
commit4219e9c13f0e64addf208c1defa13b2703beb523 (patch)
treef87e708d91c3e7400ba404664d8a9aa2da178bd1 /compiler
parent4a73e707dd61f30cc66e27050b10abd9cf4a624b (diff)
downloadhaskell-4219e9c13f0e64addf208c1defa13b2703beb523.tar.gz
Make boxed 1-tuples have known keys
Unlike other tuples, which use special syntax and are "known" by way of a special `isBuiltInOcc_maybe` code path, boxed 1-tuples do not use special syntax. Therefore, in order to make sure that the internals of GHC are aware of the `data Unit a = Unit a` definition in `GHC.Tuple`, we give `Unit` known keys. For the full details, see `Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)` in `GHC.Builtin.Types`. Fixes #18097. (cherry picked from commit 518a63d4d7e31e49a81ad66d5e5ccb1f790f6de9)
Diffstat (limited to 'compiler')
-rw-r--r--compiler/prelude/PrelInfo.hs12
-rw-r--r--compiler/prelude/PrelNames.hs4
-rw-r--r--compiler/prelude/TysWiredIn.hs40
3 files changed, 48 insertions, 8 deletions
diff --git a/compiler/prelude/PrelInfo.hs b/compiler/prelude/PrelInfo.hs
index 204b7ce9f9..1b8626c5c4 100644
--- a/compiler/prelude/PrelInfo.hs
+++ b/compiler/prelude/PrelInfo.hs
@@ -58,6 +58,7 @@ import PrelRules
import Avail
import PrimOp
import DataCon
+import BasicTypes
import Id
import Name
import NameEnv
@@ -121,14 +122,17 @@ knownKeyNames
= all_names
where
all_names =
+ -- We exclude most tuples from this list—see
+ -- Note [Infinite families of known-key names] in GHC.Builtin.Names.
+ -- We make an exception for Unit (i.e., the boxed 1-tuple), since it does
+ -- not use special syntax like other tuples.
+ -- See Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)
+ -- in GHC.Builtin.Types.
+ tupleTyConName BoxedTuple 1 : tupleDataConName Boxed 1 :
concat [ wired_tycon_kk_names funTyCon
, concatMap wired_tycon_kk_names primTyCons
-
, concatMap wired_tycon_kk_names wiredInTyCons
- -- Does not include tuples
-
, concatMap wired_tycon_kk_names typeNatTyCons
-
, map idName wiredInIds
, map (idName . primOpId) allThePrimOps
, map (idName . primOpWrapperId) allThePrimOps
diff --git a/compiler/prelude/PrelNames.hs b/compiler/prelude/PrelNames.hs
index 99fd8b28c2..978c6f5b26 100644
--- a/compiler/prelude/PrelNames.hs
+++ b/compiler/prelude/PrelNames.hs
@@ -111,6 +111,10 @@ by the user. For those things that *can* appear in source programs,
See also Note [Built-in syntax and the OrigNameCache]
+Note that one-tuples are an exception to the rule, as they do get assigned
+known keys. See
+Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)
+in GHC.Builtin.Types.
Note [The integer library]
~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/compiler/prelude/TysWiredIn.hs b/compiler/prelude/TysWiredIn.hs
index 54102f9e04..6caf62ad8b 100644
--- a/compiler/prelude/TysWiredIn.hs
+++ b/compiler/prelude/TysWiredIn.hs
@@ -69,7 +69,7 @@ module TysWiredIn (
-- * Tuples
mkTupleTy, mkTupleTy1, mkBoxedTupleTy, mkTupleStr,
- tupleTyCon, tupleDataCon, tupleTyConName,
+ tupleTyCon, tupleDataCon, tupleTyConName, tupleDataConName,
promotedTupleDataCon,
unitTyCon, unitDataCon, unitDataConId, unitTy, unitTyConKey,
pairTyCon,
@@ -700,9 +700,13 @@ for one-tuples. So in ghc-prim:GHC.Tuple we see the declarations:
data Unit a = Unit a
data (a,b) = (a,b)
-There is no way to write a boxed one-tuple in Haskell, but it can be
-created in Template Haskell or in, e.g., `deriving` code. There is
-nothing special about one-tuples in Core; in particular, they have no
+There is no way to write a boxed one-tuple in Haskell using tuple syntax.
+They can, however, be written using other methods:
+
+1. They can be written directly by importing them from GHC.Tuple.
+2. They can be generated by way of Template Haskell or in `deriving` code.
+
+There is nothing special about one-tuples in Core; in particular, they have no
custom pretty-printing, just using `Unit`.
Note that there is *not* a unary constraint tuple, unlike for other forms of
@@ -712,6 +716,29 @@ details.
See also Note [Flattening one-tuples] in MkCore and
Note [Don't flatten tuples from HsSyn] in MkCore.
+-----
+-- Wrinkle: Make boxed one-tuple names have known keys
+-----
+
+We make boxed one-tuple names have known keys so that `data Unit a = Unit a`,
+defined in GHC.Tuple, will be used when one-tuples are spliced in through
+Template Haskell. This program (from #18097) crucially relies on this:
+
+ case $( tupE [ [| "ok" |] ] ) of Unit x -> putStrLn x
+
+Unless Unit has a known key, the type of `$( tupE [ [| "ok" |] ] )` (an
+ExplicitTuple of length 1) will not match the type of Unit (an ordinary
+data constructor used in a pattern). Making Unit known-key allows GHC to make
+this connection.
+
+Unlike Unit, every other tuple is /not/ known-key
+(see Note [Infinite families of known-key names] in GHC.Builtin.Names). The
+main reason for this exception is that other tuples are written with special
+syntax, and as a result, they are renamed using a special `isBuiltInOcc_maybe`
+function (see Note [Built-in syntax and the OrigNameCache] in GHC.Types.Name.Cache).
+In contrast, Unit is just an ordinary data type with no special syntax, so it
+doesn't really make sense to handle it in `isBuiltInOcc_maybe`. Making Unit
+known-key is the next-best way to teach the internals of the compiler about it.
-}
-- | Built-in syntax isn't "in scope" so these OccNames map to wired-in Names
@@ -735,6 +762,8 @@ isBuiltInOcc_maybe occ =
"->" -> Just funTyConName
-- boxed tuple data/tycon
+ -- We deliberately exclude Unit (the boxed 1-tuple).
+ -- See Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)
"()" -> Just $ tup_name Boxed 0
_ | Just rest <- "(" `BS.stripPrefix` name
, (commas, rest') <- BS.span (==',') rest
@@ -864,6 +893,9 @@ tupleDataCon sort i | i > mAX_TUPLE_SIZE = snd (mk_tuple sort i) -- Build one
tupleDataCon Boxed i = snd (boxedTupleArr ! i)
tupleDataCon Unboxed i = snd (unboxedTupleArr ! i)
+tupleDataConName :: Boxity -> Arity -> Name
+tupleDataConName sort i = dataConName (tupleDataCon sort i)
+
boxedTupleArr, unboxedTupleArr :: Array Int (TyCon,DataCon)
boxedTupleArr = listArray (0,mAX_TUPLE_SIZE) [mk_tuple Boxed i | i <- [0..mAX_TUPLE_SIZE]]
unboxedTupleArr = listArray (0,mAX_TUPLE_SIZE) [mk_tuple Unboxed i | i <- [0..mAX_TUPLE_SIZE]]