Commit 32e18420 authored by Ryan Scott's avatar Ryan Scott Committed by Ben Gamari

Special-case record fields ending with hash when deriving Read

In commit dbd81f7e, a
regression was inadvertently introduced which caused derived `Read`
instances for record data types with fields ending in a `#` symbol
(using `MagicHash`) would no longer parse on valid output. This
is ultimately due to the same reasons as #5041, as we cannot parse
a field name like `foo#` as a single identifier. We fix this issue
by employing the same workaround as in #5041: first parse the
identifier name `foo`, then then symbol `#`.

This is accomplished by the new `readFieldHash` function in
`GHC.Read`. This will likely warrant a `base-` release.

Test Plan: make test TEST=T14918

Reviewers: tdammers, hvr, bgamari

Reviewed By: bgamari

Subscribers: rwbarton, thomie, carter

GHC Trac Issues: #14918

Differential Revision:

(cherry picked from commit d5577f44)
parent 5b0eb477
......@@ -744,8 +744,9 @@ choose_RDR = varQual_RDR gHC_READ (fsLit "choose")
lexP_RDR = varQual_RDR gHC_READ (fsLit "lexP")
expectP_RDR = varQual_RDR gHC_READ (fsLit "expectP")
readField_RDR, readSymField_RDR :: RdrName
readField_RDR, readFieldHash_RDR, readSymField_RDR :: RdrName
readField_RDR = varQual_RDR gHC_READ (fsLit "readField")
readFieldHash_RDR = varQual_RDR gHC_READ (fsLit "readFieldHash")
readSymField_RDR = varQual_RDR gHC_READ (fsLit "readSymField")
punc_RDR, ident_RDR, symbol_RDR :: RdrName
......@@ -1080,19 +1080,23 @@ gen_Read_binds get_fixity loc tycon
(nlVarPat a)
[ nlHsLit (mkHsString lbl_str)
, nlHsVarApps reset_RDR [readPrec_RDR]
(nlHsVarApps reset_RDR [readPrec_RDR])
lbl_str = unpackFS lbl
mk_read_field read_field_rdr lbl
= nlHsApps read_field_rdr [nlHsLit (mkHsString lbl)]
| isSym lbl_str = readSymField_RDR
| otherwise = readField_RDR
| isSym lbl_str
= mk_read_field readSymField_RDR lbl_str
| Just (ss, '#') <- snocView lbl_str -- #14918
= mk_read_field readFieldHash_RDR ss
| otherwise
= mk_read_field readField_RDR lbl_str
.. _release-8-4-2:
Release notes for version 8.4.2
The highlights, since the 8.4.1 release, are:
Full details
- Fix a regression in which derived `Read` instances for record data types
with field names ending with `#` (by way of :ghc-flag:`-XMagicHash`) would
no longer parse valid output.
Runtime system
Template Haskell
``ghc`` library
``base`` library
- Add the `readFieldHash` function to `GHC.Read` which behaves like
`readField`, but for a field that ends with a `#` symbol.
Build system
Included libraries
The package database provided with this distribution also contains a number of
packages other than GHC itself. See the changelogs provided with these packages
for further change information.
.. ghc-package-list::
libraries/array/array.cabal: Dependency of ``ghc`` library
libraries/base/base.cabal: Core library
libraries/binary/binary.cabal: Dependency of ``ghc`` library
libraries/bytestring/bytestring.cabal: Deppendency of ``ghc`` library
libraries/Cabal/Cabal/Cabal.cabal: Dependency of ``ghc-pkg`` utility
libraries/containers/containers.cabal: Dependency of ``ghc`` library
libraries/deepseq/deepseq.cabal: Dependency of ``ghc`` library
libraries/directory/directory.cabal: Dependency of ``ghc`` library
libraries/filepath/filepath.cabal: Dependency of ``ghc`` library
compiler/ghc.cabal: The compiler itself
libraries/ghci/ghci.cabal: The REPL interface
libraries/ghc-boot/ghc-boot.cabal: Internal compiler library
libraries/ghc-compact/ghc-compact.cabal: Core library
libraries/ghc-prim/ghc-prim.cabal: Core library
libraries/haskeline/haskeline.cabal: Dependency of ``ghci`` executable
libraries/hpc/hpc.cabal: Dependency of ``hpc`` executable
libraries/integer-gmp/integer-gmp.cabal: Core library
libraries/mtl/mtl.cabal: Dependency of ``Cabal`` library
libraries/parsec/parsec.cabal: Dependency of ``Cabal`` library
libraries/process/process.cabal: Dependency of ``ghc`` library
libraries/template-haskell/template-haskell.cabal: Core library
libraries/text/text.cabal: Dependency of ``Cabal`` library
libraries/time/time.cabal: Dependency of ``ghc`` library
libraries/transformers/transformers.cabal: Dependency of ``ghc`` library
libraries/unix/unix.cabal: Dependency of ``ghc`` library
libraries/Win32/Win32.cabal: Dependency of ``ghc`` library
libraries/xhtml/xhtml.cabal: Dependency of ``haddock`` executable
......@@ -13,6 +13,7 @@ Contents:
......@@ -37,6 +37,7 @@ module GHC.Read
, readListDefault, readListPrecDefault
, readNumber
, readField
, readFieldHash
, readSymField
-- Temporary
......@@ -376,6 +377,22 @@ readField fieldName readVal = do
-- See Note [Why readField]
-- | 'Read' parser for a record field, of the form @fieldName#=value@. That is,
-- an alphanumeric identifier @fieldName@ followed by the symbol @#@. The
-- second argument is a parser for the field value.
-- Note that 'readField' does not suffice for this purpose due to
-- < Trac #5041>.
readFieldHash :: String -> ReadPrec a -> ReadPrec a
readFieldHash fieldName readVal = do
expectP (L.Ident fieldName)
expectP (L.Symbol "#")
expectP (L.Punc "=")
{-# NOINLINE readFieldHash #-}
-- See Note [Why readField]
-- | 'Read' parser for a symbol record field, of the form @(###)=value@ (where
-- @###@ is the field name). The field name must be a symbol (operator-style),
-- e.g. @(#)@. For regular (alphanumeric) field names, use 'readField'. The
# Changelog for [`base` package](
## *TBA*
* Add the `readFieldHash` function to `GHC.Read` which behaves like
`readField`, but for a field that ends with a `#` symbol (#14918).
## *TBA*
* Bundled with GHC 8.4.1
{-# LANGUAGE MagicHash #-}
module Main where
data T a = MkT { runT :: a, (##) :: a } deriving (Read, Show)
data T# a = MkT# { runT# :: a, (###) :: a } deriving (Read, Show)
t1, t2 :: T Int
t1 = MkT (-1) 1
t2 = read $ show t1
t1#, t2# :: T# Int
t1# = MkT# (-1) 1
t2# = read $ show t1#
main :: IO ()
main = do
print t2
print t2#
MkT {runT = -1, (##) = 1}
MkT# {runT# = -1, (###) = 1}
......@@ -45,3 +45,4 @@ test('T10598_bug', normal, compile_and_run, [''])
test('T10598_run', normal, compile_and_run, [''])
test('T11535', when(opsys('mingw32'), expect_broken_for(12210, ['ghci'])),
compile_and_run, [''])
test('T14918', normal, compile_and_run, [''])
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment