GHC9.8 changed where to place DuplicateRecordFields when re-exporting records that share field names
Summary
GHC 9.8 has changed the way DuplicateRecordFields needs to be used when re-exporting records which share field names. The pragma now seems to affect modules instead of records (which is probably more correct), but causes GHC to reject some programs that it used to accept, in a way that I couldn't see mentioned in the release notes.
The pattern in the reproduction example is heavily used within the amazonka-*
family of libraries, to collect type definitions into a single Types
module per-package: https://github.com/brendanhay/amazonka/issues/969
Steps to reproduce
Given the following source files:
Export.hs
:
module Export (Foo (..), Bar (..)) where
import A (Foo (..))
import B (Bar (..))
A.hs
:
{-# LANGUAGE DuplicateRecordFields #-}
module A where
data Foo = Foo {field :: Int}
B.hs
:
-- DuplicateRecordFields seemingly not required here:
-- GHC <9.8 seems happy if at least one record is
-- declared in a module with it enabled.
module B where
data Bar = Bar {field :: Bool}
Under GHC <9.8, ghc --make Export.hs
would successfully compile. GHC 9.8 refuses to compile Export.hs
:
$ ghc --make Export.hs
[1 of 3] Compiling A ( A.hs, A.o )
[2 of 3] Compiling B ( B.hs, B.o )
[3 of 3] Compiling Export ( Export.hs, Export.o )
Export.hs:1:26: error: [GHC-97219]
Duplicate record field ‘field’ in export list:
‘Bar(..)’ exports the field ‘field’
belonging to the constructor ‘Bar’
imported from ‘B’ at Export.hs:4:11-18
(and originally defined at B.hs:3:17-21)
‘Foo(..)’ exports the field ‘field’
belonging to the constructor ‘Foo’
imported from ‘A’ at Export.hs:3:11-18
(and originally defined at A.hs:3:17-21)
Suggested fix: Perhaps you intended to use DuplicateRecordFields
|
1 | module Export (Foo (..), Bar (..)) where
| ^^^^^^^^
Moving (or adding) the {-# LANGUAGE DuplicateRecordFields #-}
to Export.hs
will make GHC 9.8.1 compile Export.hs
Expected behavior
If this change was intentional, GHC 9.8's behaviour makes more sense to me, in that the pragma is needed where the collision actually occurs. An update to the User's Guide page on DuplicateRecordFields
may be all that's required here. (Amazonka can easily adapt by updating templates and regenerating service definitions.)
Environment
- GHC version used: 9.8.1
Optional:
- Operating System:
x86_64-pc-linux-gnu
- System Architecture:
amd64