GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2024-03-28T23:18:33Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/24483Can't re-export duplicate field names from identical constructor names2024-03-28T23:18:33ZTom EllisCan't re-export duplicate field names from identical constructor namesThis is a new ticket to track [an issue explained by @adamgundry](https://gitlab.haskell.org/ghc/ghc/-/issues/13352#note_294968) in a prior (closed) ticket. That is, the following code leads to the following error. The error is still pr...This is a new ticket to track [an issue explained by @adamgundry](https://gitlab.haskell.org/ghc/ghc/-/issues/13352#note_294968) in a prior (closed) ticket. That is, the following code leads to the following error. The error is still present as of GHC 9.8. It seems like an artificial limitation and it would be great if it could be lifted. This is particularly annoying if we want to create a custom `Prelude`. It makes it impossible to create a custom `Prelude` containing two different fields with the same name, if their constructors also share the same name.
```
{-# LANGUAGE DuplicateRecordFields #-}
module A where
data S = C { foo :: Int }
{-# LANGUAGE DuplicateRecordFields #-}
module B where
data T = C { foo :: Int }
{-# LANGUAGE DuplicateRecordFields #-}
module C (S(foo), T(foo)) where
import A (S(..))
import B (T(..))
```
```
Conflicting exports for ‘foo’:
‘S(foo)’ exports ‘foo’
imported from ‘A’ at C.hs:5:28-32
(and originally defined at A.hs:3:16-18)
‘T(foo)’ exports ‘foo’
imported from ‘B’ at C.hs:6:28-32
(and originally defined at B.hs:5:14-16)
```
----
It's also an interesting puzzle to try to imagine the implementation details that allow both `foo`s to be used within the same module but not re-exported from the same module! I haven't been able to work it out ...
EDIT: Ah, I think I have an explanation: in a given module, duplicate field names are disambiguated by the module they were imported from plus the constructor name.https://gitlab.haskell.org/ghc/ghc/-/issues/24481Support NoFieldSelectors as a datatype and field annotation2024-02-26T09:45:21ZAdam GundrySupport NoFieldSelectors as a datatype and field annotationThe GHC Steering Committee has accepted [proposal 512: NoFieldSelectors as a datatype and field annotation](https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0512-nofieldselectors-per-datatype.md). This makes it possib...The GHC Steering Committee has accepted [proposal 512: NoFieldSelectors as a datatype and field annotation](https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0512-nofieldselectors-per-datatype.md). This makes it possible to annotate individual datatypes or fields as to whether they should use `FieldSelectors` or `NoFieldSelectors`.https://gitlab.haskell.org/ghc/ghc/-/issues/24174OverloadedRecordDot: "type" can't be used as a field name2023-11-15T04:02:22ZHaisheng, WuOverloadedRecordDot: "type" can't be used as a field name## Summary
* I cannot use "type" as a field name.
* Looks like same problem as #21226 #20723 but looks like it didn't fix the problem for all others reserved keywords in `reservedid`
## Steps to reproduce
Given following code:
```has...## Summary
* I cannot use "type" as a field name.
* Looks like same problem as #21226 #20723 but looks like it didn't fix the problem for all others reserved keywords in `reservedid`
## Steps to reproduce
Given following code:
```haskell
{-# LANGUAGE OverloadedRecordDot, DataKinds #-}
module Main where
import GHC.Records ( HasField(..) )
data Product = Product
{ prodName :: String
, prodType :: String
}
sampleProduct :: Product
sampleProduct = Product "Foo" "Sport"
instance HasField "type" Product String where
getField :: Product -> String
getField = prodType
main :: IO ()
main = putStrLn sampleProduct.type
```
I got compilation error:
```plaintext
[1 of 2] Compiling Main ( main.hs, main.o ) [Source file changed]
main.hs:19:31: error: [GHC-58481] parse error on input ‘type’
|
19 | main = putStrLn sampleProduct.type
```
## Expected behavior
Compile and run successfully.
## Environment
* GHC version used: 9.6.3
Optional:
* Operating System: MacOS-14.4
* System Architecture:https://gitlab.haskell.org/ghc/ghc/-/issues/23963Cannot disambiguate duplicate pattern synonym record fields in exports2023-10-06T13:18:39ZAdam GundryCannot disambiguate duplicate pattern synonym record fields in exportsConsider the following module:
```hs
{-# LANGUAGE GHC2021 #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE PatternSynonyms #-}
module RecPatSyn (B(B, x)) where
data A = MkA {x_ :: Int}
data B = MkB {x_ :: Int}
pattern A :: Int...Consider the following module:
```hs
{-# LANGUAGE GHC2021 #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE PatternSynonyms #-}
module RecPatSyn (B(B, x)) where
data A = MkA {x_ :: Int}
data B = MkB {x_ :: Int}
pattern A :: Int -> A
pattern A{x} <- MkA x
pattern B :: Int -> B
pattern B{x} <- MkB x
```
There is no way to express the fact that in the export list we mean the `x` originating from pattern synonym `B`. Hence this is rejected with an ambiguous occurrence error:
```
RecPatSyn.hs:5:19: error: [GHC-66025]
• Pattern synonyms can only be bundled with matching type constructors
Couldn't match expected type of ‘B’ with actual type of ‘A’
• In the pattern synonym record selector: x
In the export: B(B, x)
|
5 | module RecPatSyn (B(B, x)) where
| ^^^^^^^
RecPatSyn.hs:5:19: error: [GHC-87543]
• Ambiguous occurrence ‘x’.
It could refer to
either the field ‘x’ of pattern synonym ‘A’,
defined at RecPatSyn.hs:12:11,
or the field ‘x’ of pattern synonym ‘B’,
defined at RecPatSyn.hs:15:11.
• In the export: B(B, x)
|
5 | module RecPatSyn (B(B, x)) where
| ^^^^^^^
```
The "Pattern synonyms can only be bundled with matching type constructors" bit of the error seems to be bogus. Presumably the ambiguous identifier is "resolved" to the first option to allow type-checking to continue. But it leads to the awkward situation where the renamer considers it ambiguous which `x` is meant, yet the type-checker apparently "knows" that `x` cannot come from `A`.
It's not obvious to me how we could do better here, but it's an awkward corner of the `PatternSynonyms`/`DuplicateRecordFields` interaction that I wanted to record.
This was originally reported at https://discourse.haskell.org/t/how-to-export-record-pattern-synonym-duplicate-field-names-in-the-same-module/7594.https://gitlab.haskell.org/ghc/ghc/-/issues/23557`-Wunused-imports` gets confused by `NoFieldSelectors`2023-07-20T19:36:33ZSimon Hengelsol@typeful.net`-Wunused-imports` gets confused by `NoFieldSelectors`## Summary
If you use `-Wunused-imports` together with `NoFieldSelectors` then you can get false positives.
## Steps to reproduce
```haskell
{-# OPTIONS_GHC -Werror=unused-imports #-}
module Foo (main) where
import Lib (foo)
main ::...## Summary
If you use `-Wunused-imports` together with `NoFieldSelectors` then you can get false positives.
## Steps to reproduce
```haskell
{-# OPTIONS_GHC -Werror=unused-imports #-}
module Foo (main) where
import Lib (foo)
main :: IO ()
main = print foo
```
```haskell
{-# LANGUAGE NoFieldSelectors #-}
module Lib where
foo :: Int
foo = 23
data Foo = Foo {
foo :: Int
}
```
```
$ runhaskell Main.hs
Main.hs:4:13: error: [-Wunused-imports, Werror=unused-imports]
The import of ‘Foo(foo)’ from module ‘Lib’ is redundant
|
4 | import Lib (foo)
| ^^^
```
## Expected behavior
```
$ runhaskell Main.hs
23
```
## Environment
* GHC version used: 9.6.1 / 9.6.29.8.1sheafsam.derbyshire@gmail.comsheafsam.derbyshire@gmail.comhttps://gitlab.haskell.org/ghc/ghc/-/issues/23279OverloadedRecordDot ignores DEPRECATED pragma2023-08-01T19:21:58ZUladzimir StsepchankaOverloadedRecordDot ignores DEPRECATED pragma## Summary
When using record dot syntax no warning is emitted when accessing fields marked as DEPRECATED.
Same stands for OverloadedLabels though that's a bit orthogonal. Pointing just for wider context as I believe both use the same c...## Summary
When using record dot syntax no warning is emitted when accessing fields marked as DEPRECATED.
Same stands for OverloadedLabels though that's a bit orthogonal. Pointing just for wider context as I believe both use the same class-based approach, so the root of the problem and possible fixes should be the same.
Is this a known issue (or maybe intended trade-off) and just me being unable to find relevant discussions?
## Steps to reproduce
See https://gitlab.com/ste.vladimir/deprecated-fields-and-record-dot
A short summary:
``` haskell
{-# LANGUAGE DeriveGeneric #-}
module Bar where
import GHC.Generics
data Bar = Bar
{ x :: Int
, y :: Char
} deriving (Generic)
{-# DEPRECATED x "Don't use me" #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE OverloadedLabels #-}
{-# LANGUAGE OverloadedRecordDot #-}
module Foo where
import Bar
import Control.Lens
import Data.Generics.Labels ()
import GHC.Records
barRecord :: Bar
barRecord = Bar
{ x = 1 -- This shows a warning
, y = 'a'
}
barFieldAccessor :: Bar -> Int
barFieldAccessor = x -- This shows a warning
barDot :: Bar -> Int
barDot b = b.x -- This does not
barOverloadedLabel :: Bar -> Int
barOverloadedLabel = view #x -- This does not
barGetField :: Bar -> Int
barGetField = getField @"x" -- This does not
```
## Expected behavior
Roughly the behavior should be identical to ordinary record fields and field accessors: warning is emitted when accessing deprecated field.
## Environment
* GHC version used: 9.2.7
I've just used the latest GHC version in hand. Let me know if you want me to test on the latest version.Bartłomiej CieślarBartłomiej Cieślarhttps://gitlab.haskell.org/ghc/ghc/-/issues/23140Confusing OverloadedRecordDot error2023-03-21T15:50:22ZDanil BerestovConfusing OverloadedRecordDot error## Summary
OverloadedRecords throws confusing error when fields aren't imported:
`No instance for (GHC.Records.HasField "bar" Foo Int)`
Since instances should be imported with data implicitly, it's not really clear how to fix it
## S...## Summary
OverloadedRecords throws confusing error when fields aren't imported:
`No instance for (GHC.Records.HasField "bar" Foo Int)`
Since instances should be imported with data implicitly, it's not really clear how to fix it
## Steps to reproduce
Foo.hs
```haskell
module Foo where
data Foo = Foo
{ bar :: Int
, baz :: String
}
```
Qux.hs
```haskell
{-# LANGUAGE OverloadedRecordDot #-}
module Qux where
import Foo (Foo)
qux :: Foo -> Int
qux foo = foo.bar
```
Gives
```
• No instance for (GHC.Records.HasField "bar" Foo Int)
arising from selecting the field ‘bar’
• In the expression: foo.bar
In an equation for ‘qux’: qux foo = foo.bar
```
Qux.hs
```haskell
{-# LANGUAGE OverloadedRecordDot #-}
module Qux where
import Foo (Foo(..)) -- it's the fix, but it's very unobvious
qux :: Foo -> Int
qux foo = foo.bar
```
## Expected behavior
It should have right error message and it shouldn't mention any `instance` because it breaks reasoning about GHC
## Environment
* GHC version used: 9.2.5https://gitlab.haskell.org/ghc/ghc/-/issues/23040`OverloadedRecordDot` and `COLUMN`-pragmas don't play nice together2023-02-28T15:27:27ZSimon Hengelsol@typeful.net`OverloadedRecordDot` and `COLUMN`-pragmas don't play nice together## Summary
`foo.foo` is accepted while `foo{-# COLUMN 23 #-}.foo` results in a parse error.
This is surprising from a users perspective and can break `OverloadedRecordDot` with source-to-source transformations / pre-processors (as it d...## Summary
`foo.foo` is accepted while `foo{-# COLUMN 23 #-}.foo` results in a parse error.
This is surprising from a users perspective and can break `OverloadedRecordDot` with source-to-source transformations / pre-processors (as it does for me).
## Steps to reproduce
```
{-# LANGUAGE NoFieldSelectors #-}
{-# LANGUAGE OverloadedRecordDot #-}
data Foo = Foo { foo :: String }
foo :: Foo
foo = Foo "foo"
main :: IO ()
main = do
putStrLn foo.foo -- works
putStrLn foo{-# COLUMN 23 #-}.foo -- parse error
```
## Expected behavior
Both `foo.foo` and `foo{-# COLUMN 23 #-}.foo` should be accepted.
## Investigation
`foo.foo` is tokenized to:
[ITvarid "foo", ITproj False, ITvarid "bar"]
However, `foo{-# COLUMN 23 #-}.foo` is tokenized to:
[ITvarid "foo", ITproj True, ITvarid "bar"]
So from what I understand, even though this manifests as a parse error, the bug is actually in the lexer.
## Environment
* GHC version used: 9.6.0.20230111
Optional:
* Operating System: Linux
* System Architecture: x86_64https://gitlab.haskell.org/ghc/ghc/-/issues/22746How to disambiguate data family instances with duplicate record fields?2023-06-05T12:06:38ZPhil de JouxHow to disambiguate data family instances with duplicate record fields?## Summary
I have been upgrading from `ghc-8.10.7` to `ghc-9.2.5` and dealing with the `-Wambiguous-fields` warning as it is deprecating:
> This will not be supported by -XDuplicateRecordFields in future releases of GHC.
`-XOverloaded...## Summary
I have been upgrading from `ghc-8.10.7` to `ghc-9.2.5` and dealing with the `-Wambiguous-fields` warning as it is deprecating:
> This will not be supported by -XDuplicateRecordFields in future releases of GHC.
`-XOverloadedRecordDot` is very nice for field access. For record updates I've been qualifying field names to avoid the ambiguity.
I found a data family with multiple instances in the same module, each a record with `-XDuplicateRecordFields`, and could not find a way to import from this module qualified in order to disambiguate a record update.
## Steps to reproduce
See the repo https://github.com/typechecker/data-family-record-dot for these code snippets:
```haskell
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DuplicateRecordFields #-}
module DataFamily where
import Data.Kind
data Choice = A | B
data family Fam :: Choice -> Type
newtype instance Fam A = FamA{ field :: Int }
newtype instance Fam B = FamB{ field :: Bool }
```
```haskell
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE RecordWildCards #-}
module RecordUpdate where
import DataFamily (Choice(..))
import qualified DataFamily as WhoIsB (Fam(FamB), Fam(field))
toggleBool :: WhoIsB.Fam B -> WhoIsB.Fam B
toggleBool b@WhoIsB.FamB{..} =
b{ WhoIsB.field = not field}
```
```
$ cabal repl
Resolving dependencies...
Build profile: -w ghc-9.4.4 -O1
In order, the following will be built (use -v for more details):
- data-family-record-dot-0.1.0.0 (lib) (first run)
Configuring library for data-family-record-dot-0.1.0.0..
Preprocessing library for data-family-record-dot-0.1.0.0..
GHCi, version 9.4.4: https://www.haskell.org/ghc/ :? for help
[1 of 2] Compiling DataFamily ( src/DataFamily.hs, interpreted )
[2 of 2] Compiling RecordUpdate ( src/RecordUpdate.hs, interpreted )
src/RecordUpdate.hs:7:1: warning: [-Wunused-imports]
The qualified import of ‘Fam(field)’
from module ‘DataFamily’ is redundant
|
7 | import qualified DataFamily as WhoIsB (Fam(FamB), Fam(field))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/RecordUpdate.hs:11:8: warning: [-Wambiguous-fields]
The record update b {WhoIsB.field = not
field} with type DataFamily.R:FamB is ambiguous.
This will not be supported by -XDuplicateRecordFields in future releases of GHC.
|
11 | b{ WhoIsB.field = not field}
| ^^^^^^^^^^^^^^^^^^^^^^^^
Ok, two modules loaded.
```
Note that if I followed the advice of the first warning and remove the qualified import of `Fam(field)` then I get an error.
```diff
- import qualified DataFamily as WhoIsB (Fam(FamB), Fam(field))
+ import qualified DataFamily as WhoIsB (Fam(FamB))
```
```
src/RecordUpdate.hs:11:8: error:
Not in scope: ‘WhoIsB.field’
Suggested fix:
Perhaps you want to add ‘field’ to the import list in the import of
‘DataFamily’ (src/RecordUpdate.hs:7:1-49).
|
11 | b{ WhoIsB.field = not field}
|
```
## Expected behavior
I'd expect to be able to use a qualified import to disambiguate. Is there a way? A workaround is to move one of the data family instances to another module, side-stepping the duplicate record field altogether, but that has import consequences for other consumers of the module (now two imports when there was one required to import all instances).
## Environment
ghc-9.4.4 and ghc-9.2.5 are the same here.https://gitlab.haskell.org/ghc/ghc/-/issues/22382Improve Error message when field is missing on actual Haskell record2023-06-23T12:28:19ZMagnus ViernickelImprove Error message when field is missing on actual Haskell record<!--
READ THIS FIRST: If the feature you are proposing changes the language that GHC accepts
or adds any warnings to `-Wall`, it should be written as a [GHC Proposal](https://github.com/ghc-proposals/ghc-proposals/).
Other features, appr...<!--
READ THIS FIRST: If the feature you are proposing changes the language that GHC accepts
or adds any warnings to `-Wall`, it should be written as a [GHC Proposal](https://github.com/ghc-proposals/ghc-proposals/).
Other features, appropriate for a GitLab feature request, include GHC API/plugin
innovations, new low-impact compiler flags, or other similar additions to GHC.
-->
## Motivation
When having `-XOverloadedRecordDots` on and writing the following code
```haskell
data R = MkR
{ ri :: Int
, rs :: String
}
x :: R -> Bool
x r = r.rb
```
I get the following error message
```
• No instance for (GHC.Records.HasField "rb" R Bool)
arising from selecting the field ‘rb’
• In the expression: r.rb
In an equation for ‘x’: x r = r.rb
|
97 | x r = r.rb
| ^^^^
```
which is arguably too confusing if you just want to use this extension for allowing the record dot syntax.
## Proposal
As this is a Haskell record the error message could just have been "The Haskell record `R` does not have the field `rb`" which is in my opinion easier to decipher for users who don't want to use the actual overloading of the record dot. As it's possible to also declare `HasField` instances for some specific field name (`HasField "rb" R Bool`) it would probably be good to nevertheless include a NB that this error results from a missing `HasField` instance.
I would like to implement this my own, if this was accepted, but I'm new so guidance would be appreciated :smile:
Thanks in advance!https://gitlab.haskell.org/ghc/ghc/-/issues/22273ForeignFunctionInterface steals "label" undocumentedly from OverloadedRecordDot2023-03-25T19:29:13ZJade LovelaceForeignFunctionInterface steals "label" undocumentedly from OverloadedRecordDot## Summary
If you compile a program like the following with `ForeignFunctionInterface` enabled (as is (mysteriously) default in GHC2021, Haskell2010, but notably not Haskell98), it will fail to parse.
## Steps to reproduce
```
{-# LAN...## Summary
If you compile a program like the following with `ForeignFunctionInterface` enabled (as is (mysteriously) default in GHC2021, Haskell2010, but notably not Haskell98), it will fail to parse.
## Steps to reproduce
```
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE OverloadedRecordDot #-}
module Foo (Node(..)) where
newtype Node = Node
{
label :: ()
}
instance Semigroup Node where
n1 <> n2 = Node
{ label = n1.label <> n2.label
}
```
```
~ » with-ghc 924
[nix-shell:~]$ ghc OhNo.hs
[1 of 1] Compiling Foo ( OhNo.hs, OhNo.o )
OhNo.hs:12:18: error: parse error on input ‘label’
|
12 | { label = n1.label <> n2.label
| ^^^^^
However:
[nix-shell:~]$ ghc -XNoForeignFunctionInterface OhNo.hs
[1 of 1] Compiling Foo ( OhNo.hs, OhNo.o )
```
## Expected behavior
I would like the program to compile, or for the syntax-stealing to be documented.
## Environment
* GHC version used: 9.2.4
Optional:
* Operating System: Linux/macOS
* System Architecture: x86_64Andreas KlebingerAndreas Klebingerhttps://gitlab.haskell.org/ghc/ghc/-/issues/22267OverloadedRecordDot is broken when records have a constraint2023-06-07T10:31:18ZGautier DI FOLCOOverloadedRecordDot is broken when records have a constraint## Summary
Whenever I try to reference a function with a constraint with OverloadedRecordDot syntax, I have an error.
## Steps to reproduce
While this code compiles:
```
{-# LANGUAGE OverloadedRecordDot #-}
module B where
data R = R...## Summary
Whenever I try to reference a function with a constraint with OverloadedRecordDot syntax, I have an error.
## Steps to reproduce
While this code compiles:
```
{-# LANGUAGE OverloadedRecordDot #-}
module B where
data R = R {myFunc :: String -> Int}
myUsage :: R -> Int
myUsage r = r.myFunc "42"
```
Adding a constraint:
```
{-# LANGUAGE OverloadedRecordDot #-}
module B where
import GHC.Stack
data R = R {myFunc :: HasCallStack => String -> Int}
myUsage :: R -> Int
myUsage r = r.myFunc "42"
```
gives me an error:
```
B.hs:9:13: error:
• No instance for (GHC.Records.HasField "myFunc" R (String -> Int))
arising from selecting the field ‘myFunc’
(maybe you haven't applied a function to enough arguments?)
• In the expression: r.myFunc
In the expression: r.myFunc "42"
In an equation for ‘myUsage’: myUsage r = r.myFunc "42"
|
9 | myUsage r = r.myFunc "42"
```
it also fails with a more classic one:
```
{-# LANGUAGE OverloadedRecordDot #-}
module B where
data R = R {myFunc :: forall a. Show a => a -> Int}
myUsage :: R -> Int
myUsage r = r.myFunc "42"
```
which gives
```
B.hs:7:13: error:
• No instance for (GHC.Records.HasField "myFunc" R (String -> Int))
arising from selecting the field ‘myFunc’
(maybe you haven't applied a function to enough arguments?)
• In the expression: r.myFunc
In the expression: r.myFunc "42"
In an equation for ‘myUsage’: myUsage r = r.myFunc "42"
|
7 | myUsage r = r.myFunc "42"
```
## Expected behavior
I expects the type-check works as there's no constraint (while propagating it).
## Environment
* GHC version used: 9.4.2 / 9.2.2
Optional:
* Operating System: NixOS unstable
* System Architecture: x86_64Gautier DI FOLCOGautier DI FOLCOhttps://gitlab.haskell.org/ghc/ghc/-/issues/22160DisambiguateRecordFields, not DuplicateRecordFields, should control name reso...2023-03-30T13:28:41ZAdam GundryDisambiguateRecordFields, not DuplicateRecordFields, should control name resolution for record updatesAt the moment, the `DuplicateRecordFields` extension changes name resolution for record updates so that it is sufficient for one type (or, following #21443, one constructor) to have all the fields being updated. I claim that this behavio...At the moment, the `DuplicateRecordFields` extension changes name resolution for record updates so that it is sufficient for one type (or, following #21443, one constructor) to have all the fields being updated. I claim that this behaviour should be enabled by the `DisambiguateRecordFields` extension instead. This would mean `DisambiguateRecordFields` controls all the special name lookup rules for use sites, while `DuplicateRecordFields` merely allows the definition of the same field name multiple times in the same module. (I'm assuming a post-#19461 world where the type-directed resolution is gone.)
Since `DuplicateRecordFields` implies `DisambiguateRecordFields`, this change should almost always accept more programs.
Concretely, the following program is rejected with ambiguity errors on the record update, but I think it should be accepted:
```hs
module MS where
data S = MkS { x :: Int }
module MT where
data T = MkT { x :: Int, y :: Int }
module MU where
data U = MkU { y :: Int }
{-# LANGUAGE DisambiguateRecordFields #-} -- using DuplicateRecordFields here instead would work already
module N where
import MS
import MT
import MU
eg r = r { x = 1, y = 1 }
```
@sheaf you may have an opinion as this relates to !8686?sheafsam.derbyshire@gmail.comsheafsam.derbyshire@gmail.comhttps://gitlab.haskell.org/ghc/ghc/-/issues/22156HasField should allow unlifted record fields2024-02-08T08:06:00ZRichard Eisenbergrae@richarde.devHasField should allow unlifted record fieldsIf I say
```hs
data Rec = MkRec { field :: Int# }
```
I should be able to write
```
f :: Rec -> Int
f r = I# r.field
```
(with `-XOverloadedRecordDot`). But I get a kind error here. I think it would be somewhat straightforward to cha...If I say
```hs
data Rec = MkRec { field :: Int# }
```
I should be able to write
```
f :: Rec -> Int
f r = I# r.field
```
(with `-XOverloadedRecordDot`). But I get a kind error here. I think it would be somewhat straightforward to change `HasField` to be more general:
```hs
class HasField (label :: k) (record :: TYPE record_rep) (field :: field_rep) | label record -> field field_rep where
getField :: record -> field
```
Surprises always lurk, but my instinct is that this would Just Work.Adam GundryAdam Gundryhttps://gitlab.haskell.org/ghc/ghc/-/issues/22106NoFieldSelectors should prevent importing fields at top level2023-06-30T17:11:36ZAdam GundryNoFieldSelectors should prevent importing fields at top levelFrom https://gitlab.haskell.org/ghc/ghc/-/issues/21625#note_450472:
> It seems that the current implementation of `NoFieldSelectors` is inconsistent between export lists and import lists. Consider the following:
> ```hs
> {-# LANGUAGE N...From https://gitlab.haskell.org/ghc/ghc/-/issues/21625#note_450472:
> It seems that the current implementation of `NoFieldSelectors` is inconsistent between export lists and import lists. Consider the following:
> ```hs
> {-# LANGUAGE NoFieldSelectors #-}
> module M where
> data T = MkT { foo :: Int, bar :: Int }
> foo = ()
> ```
> If I instead write an export list `module M (foo)` the `foo` always refers to the value binding, not the field. I have to write `T(foo)` to export the field. (This is documented in the user's guide: https://downloads.haskell.org/ghc/9.4.1/docs/users_guide/exts/field_selectors.html#import-and-export-of-selector-functions). This means the module can choose to export the field or the value binding independently.
>
> On the other hand, currently if I write a restricted import list `import M (foo)` the `foo` refers to both the field and the value (so it generates an ambiguity error, or with a variant of !8858 would import both), while `import M (bar)` is accepted and imports the field. The user's guide doesn't appear to document what should happen in this case. I think we should be consistent with exports, so that `import M (foo)` would import only the value binding, `import M (T(foo)` would import the field, and `import M (bar)` would be an error.sheafsam.derbyshire@gmail.comsheafsam.derbyshire@gmail.comhttps://gitlab.haskell.org/ghc/ghc/-/issues/21898Problems disambiguating a record update with pattern synonyms2023-03-30T13:28:39Zsheafsam.derbyshire@gmail.comProblems disambiguating a record update with pattern synonymsThe parent of a pattern synonym record field is the pattern synonym itself, which I think makes sense (a pattern synonym behaves much like a data constructor). However, it seems that the following variant on #21443 causes GHC to trip ove...The parent of a pattern synonym record field is the pattern synonym itself, which I think makes sense (a pattern synonym behaves much like a data constructor). However, it seems that the following variant on #21443 causes GHC to trip over:
```haskell
{-# LANGUAGE DuplicateRecordFields, PatternSynonyms #-}
pattern P :: Int -> Int -> (Int, Int)
pattern P { proj_x, proj_y } = (proj_x, proj_y)
pattern Q1 :: Int -> Int
pattern Q1 { proj_x } = proj_x
pattern Q2 :: Int -> Int
pattern Q2 { proj_y } = proj_y
blah :: (Int, Int) -> (Int, Int)
blah p = p { proj_x = 0, proj_y = 1 }
```
```
error:
* GHC internal error: `T21443b.$sel:proj_x:P' is not in scope during type checking, but it passed the renamer
tcl_env of environment: [auv :-> Identifier[p::(Int,
Int), NotLetBound],
rgF :-> Identifier[blah::(Int, Int)
-> (Int, Int), TopLevelLet {} True]]
* In the expression: p {proj_x = 0, proj_y = 1}
In an equation for `blah': blah p = p {proj_x = 0, proj_y = 1}
|
| blah p = p { proj_x = 0, proj_y = 1 }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```9.8.1sheafsam.derbyshire@gmail.comsheafsam.derbyshire@gmail.comhttps://gitlab.haskell.org/ghc/ghc/-/issues/21797HieAST missing types with record-dot-syntax2022-08-04T14:18:38ZColten WebbHieAST missing types with record-dot-syntax## Summary
HieAST doesn't contain the proper type information for record dot syntax usage.
## Steps to reproduce
Here is a [sample program](https://github.com/coltenwebb/hiedemo) that demonstrates the issue. The program is written for...## Summary
HieAST doesn't contain the proper type information for record dot syntax usage.
## Steps to reproduce
Here is a [sample program](https://github.com/coltenwebb/hiedemo) that demonstrates the issue. The program is written for 9.2.2, but the output is the same for the 9.4 pre-release.
## Expected behavior
I expect HieAST to have type information for the nodes that correspond to the use of record-dot-syntax. Instead, the node corresponding to `x.b` has no type information, shown below.
```
Node@app/Test.hs:14:17-19: Source: From source
{(annotations: {(HsApp, HsExpr), (XExpr, HsExpr)}),
(types: []), (identifier info: {})}
```
The full outputs/comparison are also shown in the readme of the sample program above.
## Environment
* GHC version used: 9.2.2
* (also tested on 9.4 prerelease with some modifications to sample code, but gives identical output)9.4.1ZubinColten WebbZubinhttps://gitlab.haskell.org/ghc/ghc/-/issues/21720DuplicateRecordFields doesn't work with TH-generated records2023-03-30T13:28:39ZMichael Peyton JonesDuplicateRecordFields doesn't work with TH-generated records## Summary
There are a bunch of tickets about the fact that TH doesn't really work with `DuplicateRecordFields`, but I couldn't find one for this specific issue.
Generating multiple records using TH whose fields share textual names doe...## Summary
There are a bunch of tickets about the fact that TH doesn't really work with `DuplicateRecordFields`, but I couldn't find one for this specific issue.
Generating multiple records using TH whose fields share textual names does not work. The generated code passes the typechecker but generates linker errors, e.g.
```
/run/user/1000/ghc1993779_0/ghc_11.s:79586:0: error:
Error: symbol `lspzmtypeszm1zi5zi0zi0zminplace_LanguageziLSPziMetaModelziGenerated_textDocument_info' is already defined
|
79586 | lspzmtypeszm1zi5zi0zi0zminplace_LanguageziLSPziMetaModelziGenerated_textDocument_info:
```
I guess that the generated fields are not getting mangled as described in https://gitlab.haskell.org/ghc/ghc/-/issues/11103.
## Steps to reproduce
Generate records which have duplicated fields using e.g. `newName "fieldA"` twice, enable `DuplicateRecordFields`. Observe linker errors.
e.g. (not compiled)
```
noBang = Bang NoSourceUnpackedness NoSourceStrictness
mkRecords = do
tn1 <- newName "R1"
cn1 <- newName "C1"
fn1 <- newName "f"
let r1 = DataD [] tn1 [] Nothing [RecC cn1 [(fn1, noBang, ConT ''Integer)]] []
tn2 <- newName "R2"
cn2 <- newName "C2"
fn2 <- newName "f"
let r2 = DataD [] tn2 [] Nothing [RecC cn2 [(fn2, noBang, ConT ''Integer)]] []
$mkRecords
```
## Expected behavior
Allow the duplicated record fields
## Environment
* GHC version used: Observed on both 8.10.7 and 9.0.2sheafsam.derbyshire@gmail.comsheafsam.derbyshire@gmail.comhttps://gitlab.haskell.org/ghc/ghc/-/issues/21690Question: Feasibility of polymorphic field selectors2022-06-11T14:43:01ZparsonsmattQuestion: Feasibility of polymorphic field selectorsPlease let me know if there's a better place to ask feasibility questions.
I was just lamenting in the work chat how `DuplicateRecordFields` isn't quite smart enough, so we had to invent all this `OverloadedRecordDot` to work with it co...Please let me know if there's a better place to ask feasibility questions.
I was just lamenting in the work chat how `DuplicateRecordFields` isn't quite smart enough, so we had to invent all this `OverloadedRecordDot` to work with it correctly. It occurred to me that top-level field selectors could just be given polymorphic types.
Supposing we had a module like this,
```haskell
module X where
data Foo = Foo { name :: String, age :: Int }
```
Currently, we generate these top-level functions, ish
```haskell
name :: Foo -> String
name (Foo n _) = n
age :: Foo -> Int
age (Foo _ a) = a
```
But, we could instead generate these:
```haskell
name :: HasField "name" a b => a -> b
name = getField @"name"
age :: HasField "age" a b => a -> b
age = getField @"age"
```
This seems somewhat obvious to me, which makes me suspicious that it must have been considered and rejected for some reason previously. A brief search was unable to find anything on this. So I'm curious if there's any reason this wouldn't be easy to support.
It would be pretty easy to support this with `TemplateHaskell` and `NoFieldSelectors`, so I can definitely see why we'd want to just use `NoFieldSelectors` and let anyone who wants to do anything other than the standard rely on that.https://gitlab.haskell.org/ghc/ghc/-/issues/21625Import/export of field selectors: undocumented breaking change in ghc 9.2 fro...2023-01-23T11:51:59ZPranay SashankImport/export of field selectors: undocumented breaking change in ghc 9.2 from ghc 9.0## Summary
GHC 9.2's imports behave differently than GHC 9.0 or 8.10 when `DuplicateRecordFields` are used. I am guessing this change is inadvertently introduced while implementing ghc proposal https://github.com/ghc-proposals/ghc-propo...## Summary
GHC 9.2's imports behave differently than GHC 9.0 or 8.10 when `DuplicateRecordFields` are used. I am guessing this change is inadvertently introduced while implementing ghc proposal https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0366-no-ambiguous-field-access.rst#alternatives (but also could have been any of the record changes introduced)
## Steps to reproduce
Consider the following set of modules
```haskell
-- B.hs
{-# LANGUAGE DuplicateRecordFields #-}
module B where
data B = B {f1 :: Int, f2 :: String}
data C = C {f1 :: Char, f2 :: Int}
fellow :: Int
fellow = 3
```
```haskell
-- T.hs
{-# LANGUAGE DuplicateRecordFields #-}
module T where
import B hiding (fellow, f1)
t :: IO ()
t = pure ()
```
With ghc 9.0
```
[nix-shell:~/src/bug]$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 9.0.2
[nix-shell:~/src/bug]$ ghc B.hs T.hs
[1 of 2] Compiling B ( B.hs, B.o )
[2 of 2] Compiling T ( T.hs, T.o )
```
however with ghc 9.2
```
[nix-shell:~/src/bug]$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 9.2.2
[nix-shell:~/src/bug]$ ghc B.hs T.hs
[1 of 2] Compiling B ( B.hs, B.o )
[2 of 2] Compiling T ( T.hs, T.o )
T.hs:5:26: error:
Ambiguous name ‘f1’ in import item. It could refer to:
B.C(f1)
B.B(f1)
|
5 | import B hiding (fellow, f1)
| ^^
```
The issue happens in normal imports as well, not just hiding imports
```haskell
-- T.hs
{-# LANGUAGE DuplicateRecordFields #-}
module T where
import B (fellow, f1)
t :: IO ()
t = pure ()
```
```
[nix-shell:~/src/bug]$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 9.2.2
[nix-shell:~/src/bug]$ ghc B.hs T.hs
[1 of 2] Compiling B ( B.hs, B.o )
[2 of 2] Compiling T ( T.hs, T.o )
T.hs:5:11: error:
Ambiguous name ‘f1’ in import item. It could refer to:
B.B(f1)
B.C(f1)
|
5 | import B (f1, fellow)
| ^^
```
## Expected behavior
`import B hiding (f1)` behaviour should be similar to ghc 9.0.
I am not sure if `import B (f1)` should be similar to previous behaviour, but this change should be documented.
Given that ambiguous fields updates are currently a warning, I don't think any of the above should be an error. Looking through the proposal I don't find any mention of this affecting imports.
In my use case I have a module that re-exports a bunch of other modules which have duplicate record fields (say min is the field). I could previously do `import Exporter hiding (min)` if I wanted to use `min` function from prelude. Now I instead do a `Prelude.min`, but it'd be nice to have the previous behaviour here.
## Environment
* GHC version used: 8.10.7, 9.0.2, 9.2.2
Optional:
* Operating System: nixos
* System Architecture: x86-649.6.1Adam GundryAdam Gundry