diff options
author | Adam Gundry <adam@well-typed.com> | 2020-12-23 22:22:08 +0000 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2021-02-16 04:34:43 -0500 |
commit | 2521b041bff00458cb2c84b8747ea60d6991e329 (patch) | |
tree | 091e47028c452050ee46fcb70aa9a01186120c1e /testsuite/tests/overloadedrecflds/should_compile | |
parent | f422c12d26f183481ad8a833667cbfdd1c9b3e95 (diff) | |
download | haskell-2521b041bff00458cb2c84b8747ea60d6991e329.tar.gz |
Implement NoFieldSelectors extension (ghc-proposals 160)
Fixes #5972. This adds an extension NoFieldSelectors to disable the generation
of selector functions corresponding to record fields. When this extension is
enabled, record field selectors are not accessible as functions, but users are
still able to use them for record construction, pattern matching and updates.
See Note [NoFieldSelectors] in GHC.Rename.Env for details.
Defining the same field multiple times requires the DuplicateRecordFields
extension to be enabled, even when NoFieldSelectors is in use.
Along the way, this fixes the use of non-imported DuplicateRecordFields in GHCi
with -fimplicit-import-qualified (fixes #18729).
Moreover, it extends DisambiguateRecordFields to ignore non-fields when looking
up fields in record updates (fixes #18999), as described by
Note [DisambiguateRecordFields for updates].
Co-authored-by: Simon Hafner <hafnersimon@gmail.com>
Co-authored-by: Fumiaki Kinoshita <fumiexcel@gmail.com>
Diffstat (limited to 'testsuite/tests/overloadedrecflds/should_compile')
7 files changed, 100 insertions, 0 deletions
diff --git a/testsuite/tests/overloadedrecflds/should_compile/NFSDRF.hs b/testsuite/tests/overloadedrecflds/should_compile/NFSDRF.hs new file mode 100644 index 0000000000..a1e8744974 --- /dev/null +++ b/testsuite/tests/overloadedrecflds/should_compile/NFSDRF.hs @@ -0,0 +1,36 @@ +{-# LANGUAGE NoFieldSelectors #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE DuplicateRecordFields #-} + +module NFSDRF where + +import Prelude + + +data Foo = Foo { foo :: Int, bar :: String } +data Bar = Bar { foo :: Int, bar' :: String } + +foo = 3 -- should not conflict + +fooX = foo + 1 + +rwcPatFoo Foo{..} = show (foo, bar) +rwcConFoo = Foo{..} where + foo = 42 + bar = "hello" + +foo1 :: Foo +foo1 = Foo 3 "bar" + +foo2 = Foo { foo = 3, bar = "bar" } -- disambiguate foo + + +-- foo3 :: Foo +-- foo3 = foo1 { foo = 4 } -- currently rejected, see #18999 + +foo4 = foo1 { bar = "baz" } -- unambiguous + +bar0 = Bar { foo = 0, bar' = "bar'" } + +-- bar1 :: Bar +-- bar1 = bar0 { foo = 1 } -- currently rejected, see #18999 diff --git a/testsuite/tests/overloadedrecflds/should_compile/NFSExport.hs b/testsuite/tests/overloadedrecflds/should_compile/NFSExport.hs new file mode 100644 index 0000000000..8e83c085bf --- /dev/null +++ b/testsuite/tests/overloadedrecflds/should_compile/NFSExport.hs @@ -0,0 +1,8 @@ +{-# LANGUAGE NoFieldSelectors #-} + +module NFSExport (T(foo), def) where + +data T = MkT { foo :: Bool } + +def :: T +def = MkT False diff --git a/testsuite/tests/overloadedrecflds/should_compile/NFSImport.hs b/testsuite/tests/overloadedrecflds/should_compile/NFSImport.hs new file mode 100644 index 0000000000..433e9f06fc --- /dev/null +++ b/testsuite/tests/overloadedrecflds/should_compile/NFSImport.hs @@ -0,0 +1,5 @@ +module NFSImport where + +import NFSExport + +t = def { foo = True } diff --git a/testsuite/tests/overloadedrecflds/should_compile/NoFieldSelectors.hs b/testsuite/tests/overloadedrecflds/should_compile/NoFieldSelectors.hs new file mode 100644 index 0000000000..d114861672 --- /dev/null +++ b/testsuite/tests/overloadedrecflds/should_compile/NoFieldSelectors.hs @@ -0,0 +1,30 @@ +{-# LANGUAGE NoFieldSelectors #-} +{-# LANGUAGE RecordWildCards #-} + + +module NoFieldSelectors +where + +import Prelude + + +data Foo = Foo { foo :: Int, bar :: String } + +{-# ANN foo () #-} +foo = 3 -- should not conflict + +fooX = foo + 1 + +rwcPatFoo Foo{..} = show (foo, bar) +rwcConFoo = Foo{..} where + foo = 42 + bar = "hello" + +foo1 :: Foo +foo1 = Foo 3 "bar" + +foo2 = Foo { foo = 3, bar = "bar" } -- disambiguate foo + +-- foo3 = foo1 { foo = 4 } -- currently rejected, see #18999 + +foo4 = foo1 { bar = "baz" } -- bar is unambiguous diff --git a/testsuite/tests/overloadedrecflds/should_compile/T18999_FieldSelectors.hs b/testsuite/tests/overloadedrecflds/should_compile/T18999_FieldSelectors.hs new file mode 100644 index 0000000000..8fb6e5f9df --- /dev/null +++ b/testsuite/tests/overloadedrecflds/should_compile/T18999_FieldSelectors.hs @@ -0,0 +1,7 @@ +{-# LANGUAGE DisambiguateRecordFields #-} +module T18999_FieldSelectors where + +data Foo = Foo { not :: Int } + +foo = Foo { not = 1 } +y = foo { not = 2 } diff --git a/testsuite/tests/overloadedrecflds/should_compile/T18999_NoFieldSelectors.hs b/testsuite/tests/overloadedrecflds/should_compile/T18999_NoFieldSelectors.hs new file mode 100644 index 0000000000..69bf8fb427 --- /dev/null +++ b/testsuite/tests/overloadedrecflds/should_compile/T18999_NoFieldSelectors.hs @@ -0,0 +1,9 @@ +{-# LANGUAGE DisambiguateRecordFields #-} +{-# LANGUAGE NoFieldSelectors #-} +module T18999_NoFieldSelectors where + +data Foo = Foo { bar :: Int, baz :: Int } +baz = 42 + +foo = Foo { bar = 23, baz = 1 } +y = foo { baz = baz } diff --git a/testsuite/tests/overloadedrecflds/should_compile/all.T b/testsuite/tests/overloadedrecflds/should_compile/all.T index 515b19635f..a043570034 100644 --- a/testsuite/tests/overloadedrecflds/should_compile/all.T +++ b/testsuite/tests/overloadedrecflds/should_compile/all.T @@ -3,3 +3,8 @@ test('T12609', normal, compile, ['']) test('T16597', [], multimod_compile, ['T16597', '-v0']) test('T17176', normal, compile, ['']) test('DRFPatSynExport', [], makefile_test, ['DRFPatSynExport']) +test('NoFieldSelectors', normal, compile, ['']) +test('NFSDRF', normal, compile, ['']) +test('NFSImport', [extra_files(['NFSExport.hs'])], multimod_compile, ['NFSImport NFSExport', '-v0']) +test('T18999_NoFieldSelectors', normal, compile, ['']) +test('T18999_FieldSelectors', normal, compile, ['']) |