diff options
author | Ryan Scott <ryan.gl.scott@gmail.com> | 2020-04-27 17:08:19 -0400 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2020-05-31 18:03:38 -0400 |
commit | 4219e9c13f0e64addf208c1defa13b2703beb523 (patch) | |
tree | f87e708d91c3e7400ba404664d8a9aa2da178bd1 /compiler | |
parent | 4a73e707dd61f30cc66e27050b10abd9cf4a624b (diff) | |
download | haskell-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.hs | 12 | ||||
-rw-r--r-- | compiler/prelude/PrelNames.hs | 4 | ||||
-rw-r--r-- | compiler/prelude/TysWiredIn.hs | 40 |
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]] |